// dtree_util.c
// ------------
// Written by Sanmay Das for CS 181, Spring 2000
// Updated by Dan Weiss for CS 181, Spring 2001
// Updated by John Lai for CS 181, Spring 2010
// Do NOT modify this file

#include <assert.h>
#include <iostream>
#include <istream>
#include <sstream>
#include <stdio.h>
#include <unistd.h>
#include "dtree_util.h"

using namespace std;

// ValidateInput
// --------------
// Validate command line arguments
// Returns 0 on success; -1 on failure
int ValidateInput(int argc, char **argv, int &noisyFlag, 
                  int &pruneFlag, int &valSetSize,
                  int &boostFlag, int &learnerDepth,
                  int &numRounds) {
  int arg;

  valSetSize = noisyFlag = pruneFlag = boostFlag = 0;
  optarg = NULL;
  learnerDepth = -1;
  while((arg = getopt(argc, argv, "np:b:d:")) != -1) {
    switch(arg) {
	  // Use the noisy dataset
	  case 'n':
	    if(noisyFlag) {
		  return -1;
		
		} else {
		  noisyFlag = 1; 
		} 
		break; 

    case 'd':
      learnerDepth = atoi(optarg);
      break;

    case 'b': {
      boostFlag = 1;
      numRounds = atoi(optarg);
      break;
    }
		
	  // Prune the decision tree 
	  // Get the desired validation set size
	  case 'p':
	    if(pruneFlag) {
		  return -1;

		} else {
		  pruneFlag = 1;
		  valSetSize = atoi(optarg);
		}

		break;

	  // Signal an error
	  default:
	    return -1;
	}
  }

  return 0;
}

// ParseInput
// -----------
// Parses input from a file into an array of insts using C++ stream features
// Returns 0 on success; -1 on failure
int ParseInput(const DatasetDescription& DD, inst *dataset, int n, FILE *datafile)
{
  char buffer[MAXLINE];

  // For each line, read into buffer, then convert to a stream, then read from
  // the stream into dataset[i].attribute[j] or dataset[i].classifier
  for(int i = 0; i < n; i++) {
    char* retval = fgets(buffer, MAXLINE, datafile);
    assert(retval != NULL);
    string bufstring(buffer);
    istringstream is(bufstring, istringstream::in);
    for(int j = 0; j < DD.numattribs; j++) {
      is >> dataset[i].attribs[j];
      if(!is) {
        cout << "Error in datafile, line " << i << endl;
		    return -1;
      }
    }

    is >> dataset[i].classifier;
    // Default weight is 1.0/n
    dataset[i].weight = 1.0/n;
  }

  return 0;
}

// PrintOutput
// ------------
// Trivial function for printing the data stored in an inst array in the 
// format that it was read-in in
// Useful for error-checking
void PrintOutput(const DatasetDescription& DD, inst *dataset, int n)
{
  int i, j;

  for(i = 0; i < n; i++) {
    for(j = 0; j < DD.numattribs; j++) {
      cout << dataset[i].attribs[j] << " ";
	}

    cout << dataset[i].classifier << endl;
  }
}    
